using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Commons;
using WPFBPMN.Utils;

namespace CustomControls
{
    public partial class BPMNConnectingObject : UserControl
    {
       public  ConnectionType ConnectingType = ConnectionType.Sequence;

        Polyline line = new Polyline();
        BPMNShape fromDrawing;
        BPMNShape toDrawing;
        int fromIndex = -1;
        int toIndex = -1;
        BPMNShape canvas;

        public int FromIndex
        {
            get
            {
                return fromIndex;
            }
            set
            {
                fromIndex = value;
            }
        }
        public int ToIndex
        {
            get
            {
                return toIndex;
            }
            set
            {
                toIndex = value;
            }
        }
        public Polyline Line
        {
            get
            {
                return line;
            }
            set
            {
                line = value;
            }
        }
        public BPMNShape FromDrawing
        {
            get
            {
                return fromDrawing;
            }
            set
            {
                fromDrawing = value;
                CheckThisAddedToBPMNShape(fromDrawing);

            }
        }
        public BPMNShape ToDrawing
        {
            get
            {
                return toDrawing;
            }
            set
            {
                toDrawing = value;
                CheckThisAddedToBPMNShape(toDrawing);
            }
        }

        public BPMNConnectingObject(BPMNShape canvas)
        {

            this.canvas = canvas;
            line.Points.Add(new Point());
            line.Points.Add(new Point());
            line.Points.Add(new Point());
            this.Content = line;
        }

        private void CheckThisAddedToBPMNShape(BPMNShape drawing)
        {
            bool found = false;
            foreach (BPMNConnectingObject connectingObject in drawing.ConnectingObjects)
            {
                if (connectingObject == this)
                {
                    found = true;
                }
            }
            if (!found)
            {
                drawing.ConnectingObjects.Add(this);
            }
        }

        public void UpdateLocation()
        {
            ChooseBestDistance();
            line.Points[0] = new Point(fromDrawing.ConnectingPoints[fromIndex].X, fromDrawing.ConnectingPoints[fromIndex].Y);
            line.Points[2] = new Point(toDrawing.ConnectingPoints[toIndex].X, toDrawing.ConnectingPoints[toIndex].Y);
            line.Points[1] = new Point(line.Points[0].X, line.Points[2].Y);
        }

        private void ChooseBestDistance()
        {
            int _index1 = 0;
            int _index2 = 0;
            double _distance = double.MaxValue;
            for (int i = 0; i < fromDrawing.ConnectingPoints.Length; i++)
            {
                for (int j = 0; j < toDrawing.ConnectingPoints.Length; j++)
                {
                    double d = Distance(fromDrawing.ConnectingPoints[i], toDrawing.ConnectingPoints[j]);
                    if (d < _distance)
                    {
                        _distance = d;
                        _index1 = i;
                        _index2 = j;
                    }
                }
            }
            fromIndex = _index1;
            toIndex = _index2;
        }

        private double Distance(Point a, Point b)
        {
            double x = a.X - b.X;
            double y = a.Y - b.Y;
            return Math.Sqrt(x * x + y * y);
        }

        

    }


    public class BPMNConnectingMessage : BPMNConnectingObject
    {
        public BPMNConnectingMessage(BPMNShape canvas)
            : base(canvas)
        {
            ConnectingType = ConnectionType.Message;
            
            Line.Stroke = Brushes.Black;
            Line.StrokeThickness = 1;
        }
    }
    public class BPMNConnectingSequence : BPMNConnectingObject
    {
        public BPMNConnectingSequence(BPMNShape canvas)
            : base(canvas)
        {
            ConnectingType = ConnectionType.Sequence;
            Line.Stroke = Brushes.Black;
            Line.StrokeThickness = 1;
        }
    }
}